package actor.route.consistenthashing

import actor.route.consistenthashing.MoneyCounter1.{OneHand, ReportTotal}
import actor.route.consistenthashing.MoneyCounter1.{OneHand, ReportTotal}
import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
import akka.routing.ConsistentHashingPool

/**
 * @Description: define `hashMapping` / `withHashMapper`
 * @Author: DJJ
 * @Date: 2019/12/19 20:04
 */
object MoneyCounter1 {

  sealed trait Counting

  case class OneHand(cur: String, amt: Double) extends Counting

  case class ReportTotal(cur: String) extends Counting

}
class MoneyCounter1 extends Actor with ActorLogging {
  var currency: String = null
  var amount: Double = 0
  override def receive: Receive = {
    case OneHand(cur,amt) =>
      currency = cur
      amount += amt
      log.info(s"${self.path.name} received one hand of $amt$cur")
    case ReportTotal(_) =>
      log.info(s"${self.path.name} has a total of $amount$currency")
  }
}
object HashingRouter extends App {
  import MoneyCounter1._

  val currencies = List("RMB","USD","EUR","JPY","GBP","DEM","HKD","FRF","CHF")

  val routerSystem = ActorSystem("routerSystem")

  def mcHashMapping: PartialFunction[Any,Any] = {
    case OneHand(cur,_) => cur
    case ReportTotal(cur) => cur
  }

  /**
   * 特别要注意nrOfInstances，这个参数必须比消息类型的数量大才行，否则Router会错误引导消息
   */
  val router = routerSystem.actorOf(ConsistentHashingPool(
    //mcHashMapping 定义消息的类型
    nrOfInstances = 5,hashMapping = mcHashMapping,virtualNodesFactor = 2)
    .props(Props[MoneyCounter1]),name = "moneyCounter" )


  router ! OneHand("RMB",10.00)
  router ! OneHand("USD",10.00)
  router ! OneHand("HKD",10.00)
  router ! OneHand("RMB",10.00)
  router ! OneHand("CHF",10.00)

  router ! ReportTotal("RMB")
  router ! ReportTotal("USD")

  scala.io.StdIn.readLine()

  routerSystem.terminate()
}